<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
import ToolCard from '@/components/ToolCard.vue'
import { ElMessage, ElMessageBox, ElDialog, ElTable, ElTableColumn, ElTag, ElButton, ElSelect, ElOption, ElLoading } from 'element-plus'

const router = useRouter()

// Define tool interface
interface Tool {
  id: string;
  name: string;
  description: string | null;
  target_api_url: string;
  openapi_spec_url?: string;
  base_url?: string;
  auth_header?: string;
  path_filter?: string;
}

// Reactive state for the list of tools
const tools = ref<Tool[]>([])

// Log dialog state
const logDialogVisible = ref(false)
const selectedToolLogs = ref<any[]>([])
const selectedToolName = ref('')
const selectedToolId = ref('') // Store tool ID for MCP name lookup
const currentMcpNames = ref<string[]>([]) // Store current MCP technical names
const logLevel = ref('')
const logLimit = ref(100)

// Table expansion state
const expandedRows = ref<string[]>([])

// Base URL for our backend API - use relative path for proxy
const API_BASE_URL = '/api/v1'

// Function to fetch tools from the backend
const fetchTools = async () => {
  try {
    const response = await axios.get(`${API_BASE_URL}/tools/`)
    tools.value = response.data
  } catch (error) {
    ElMessage({
      message: '获取工具列表失败。',
      type: 'error',
      duration: 3000,
      showClose: true,
      grouping: true
    })
    console.error(error)
  }
}

// Function to fetch logs for a specific tool with enhanced error handling
const fetchToolLogs = async (toolName: string) => {
  if (!toolName) {
    ElMessage({
      message: '工具名称不能为空',
      type: 'warning',
      duration: 3000,
      showClose: true,
      grouping: true
    })
    return
  }
  
  // Show loading state
  const loading = ElLoading.service({
    text: '正在获取日志...',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  
  try {
    // Validate and sanitize input parameters
    const params = new URLSearchParams()
    
    // Sanitize tool name
    const sanitizedToolName = toolName.trim().substring(0, 100)
    if (sanitizedToolName) params.append('tool', sanitizedToolName)
    
    // Validate log level
    const validLevels = ['DEBUG', 'INFO', 'WARN', 'ERROR']
    if (logLevel.value && validLevels.includes(logLevel.value.toUpperCase())) {
      params.append('level', logLevel.value.toUpperCase())
    }
    
    // Validate and constrain limit
    const limit = Math.max(1, Math.min(500, parseInt(logLimit.value.toString()) || 50))
    params.append('limit', limit.toString())
    
    // Make request with timeout and error handling
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout
    
    const response = await axios.get(`${API_BASE_URL}/logs?${params.toString()}`, {
      timeout: 10000,
      signal: controller.signal,
      headers: {
        'Content-Type': 'application/json'
      }
    })
    
    clearTimeout(timeoutId)
    
    // Validate response structure
    if (!response.data || typeof response.data !== 'object') {
      throw new Error('服务器返回了无效的响应格式')
    }
    
    if (!response.data.success) {
      throw new Error(response.data.message || '服务器返回失败状态')
    }
    
    // Validate logs array
    const logs = response.data.logs
    
    // Handle null or undefined logs - convert to empty array
    let validLogs = []
    if (logs === null || logs === undefined) {
      console.info('No logs returned from server, using empty array')
      validLogs = []
    } else if (!Array.isArray(logs)) {
      console.warn('Invalid logs data type:', typeof logs, logs)
      throw new Error('日志数据格式错误：期望数组但得到 ' + typeof logs)
    } else {
      validLogs = logs
    }
    
    // Clean and validate log entries
    const cleanedLogs = validLogs.map((log, index) => {
      // Ensure log is an object
      if (!log || typeof log !== 'object') {
        console.warn(`Invalid log entry at index ${index}:`, log)
        return null
      }
      
      // Clean the log entry
      return {
        ...log,
        timestamp: log.timestamp || null,
        level: log.level || 'INFO',
        message: log.message || '无消息',
        category: log.category || 'UNKNOWN',
        details: log.details || '',
        duration: log.duration || '',
        status_code: log.status_code || null,
        url: log.url || '',
        tool_name: log.tool_name || ''
      }
    }).filter(log => log !== null) // Remove invalid entries
    
    selectedToolLogs.value = cleanedLogs
    
    // 不在这里显示成功消息，而是在合并完所有日志后显示
    // ElMessage.success(`成功获取 ${cleanedLogs.length} 条日志记录`)
    
  } catch (error: any) {
    console.error('获取日志失败:', error)
    selectedToolLogs.value = []
    
    // Enhanced error handling with specific error types
    let errorMessage = '获取日志失败'
    
    if (error.name === 'AbortError' || error.code === 'ECONNABORTED') {
      errorMessage = '请求超时，请检查网络连接或稍后重试'
    } else if (error.response) {
      // Server responded with error status
      const status = error.response.status
      const data = error.response.data
      
      switch (status) {
        case 400:
          errorMessage = `请求参数错误: ${data.message || data}`
          break
        case 404:
          errorMessage = '日志服务未找到，请检查MCP-Link是否正常运行'
          break
        case 429:
          errorMessage = '请求过于频繁，请稍后重试'
          break
        case 500:
          errorMessage = '服务器内部错误，请联系管理员'
          break
        default:
          errorMessage = `服务器错误 (${status}): ${data.message || data || '未知错误'}`
      }
    } else if (error.request) {
      // Network error
      errorMessage = '无法连接到日志服务，请检查管理API是否正常运行 (端口:5001)'
    } else if (error.message) {
      errorMessage = error.message
    }
    
    ElMessage({
      message: errorMessage,
      type: 'error',
      duration: 5000,
      showClose: true,
      grouping: true
    })
  } finally {
    loading.close()
  }
}

// Fetch tools when the component is mounted
onMounted(() => {
  fetchTools()
})

// Function to format timestamp with comprehensive error handling
const formatTimestamp = (timestamp: any): string => {
  // Handle various falsy values
  if (timestamp === null || timestamp === undefined || timestamp === '' || timestamp === 0) {
    return '无效时间'
  }
  
  // Handle non-string, non-number types
  if (typeof timestamp !== 'string' && typeof timestamp !== 'number') {
    console.warn('Invalid timestamp type:', typeof timestamp, timestamp)
    return '类型错误'
  }
  
  try {
    // Convert to string for consistent processing
    const timestampStr = String(timestamp).trim()
    
    // Check for empty string after trimming
    if (!timestampStr) {
      return '无效时间'
    }
    
    // Try to create Date object
    const date = new Date(timestampStr)
    
    // Check if the date is valid
    if (isNaN(date.getTime())) {
      console.warn('Invalid timestamp format:', timestampStr)
      return '时间格式错误'
    }
    
    // Check for reasonable date range (1970-2100)
    const year = date.getFullYear()
    if (year < 1970 || year > 2100) {
      console.warn('Date out of reasonable range:', timestampStr, 'Year:', year)
      return '日期超出范围'
    }
    
    // Format with Chinese locale
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false
    })
  } catch (error) {
    console.error('Error formatting timestamp:', error, 'Original timestamp:', timestamp)
    return '时间解析失败'
  }
}

// Function to get tag type based on log level
const getLogLevelTagType = (level: string) => {
  switch (level) {
    case 'ERROR': return 'danger'
    case 'WARN': return 'warning'
    case 'INFO': return 'success'
    case 'DEBUG': return 'info'
    default: return 'info' // 返回'info'而不是空字符串
  }
}

// Function to get tag type based on status code
const getStatusCodeTagType = (statusCode: number) => {
  if (statusCode >= 200 && statusCode < 300) return 'success'
  if (statusCode >= 400 && statusCode < 500) return 'warning'
  if (statusCode >= 500) return 'danger'
  return 'info' // 返回'info'而不是空字符串
}

// Function to get tag type for category
const getCategoryTagType = (category: string) => {
  if (category.includes('ERROR')) {
    return 'danger'
  } else if (category.includes('COMPLETE')) {
    return 'success'
  } else if (category.includes('START')) {
    return 'primary'
  } else if (category.includes('RESPONSE')) {
    return 'warning'
  } else if (category.includes('REQUEST')) {
    return 'info'
  }
  return 'info' // 返回'info'而不是空字符串
}

// Function to format category display
const formatCategoryDisplay = (category: string) => {
  // Map verbose category names to shorter display names
  const categoryMap: { [key: string]: string } = {
    'API_CALL_START': '开始',
    'API_CALL_PARAMS': '参数',
    'API_CALL_PARAM_SEPARATION': '参数分离',
    'API_CALL_REQUEST_BODY': '请求体',
    'API_CALL_URL': 'URL',
    'API_CALL_REQUEST_SUMMARY': '请求汇总',
    'API_CALL_HEADERS': '请求头',
    'API_CALL_RESPONSE': '响应',
    'API_CALL_RESPONSE_BODY': '响应体',
    'API_CALL_ERROR_RESPONSE': '错误响应',
    'API_CALL_COMPLETE': '完成',
    'API_CALL_ERROR': '错误',
    'API_CALL_MERGED': 'API调用' // New merged category
  }
  return categoryMap[category] || category
}

// Function to format details content for display
const formatDetailsContent = (details: string) => {
  if (!details) return ''
  
  try {
    // Try to parse as JSON and format it
    const parsed = JSON.parse(details)
    return JSON.stringify(parsed, null, 2)
  } catch {
    // If not JSON, return as-is
    return details
  }
}

// Function to toggle row expansion
const toggleRowExpansion = (row: any) => {
  const rowKey = row.timestamp
  const index = expandedRows.value.indexOf(rowKey)
  if (index > -1) {
    // Row is expanded, collapse it
    expandedRows.value.splice(index, 1)
  } else {
    // Row is collapsed, expand it
    expandedRows.value.push(rowKey)
  }
}

// Function to check if row is expanded
const isRowExpanded = (row: any) => {
  return expandedRows.value.includes(row.timestamp)
}

// Function to merge logs from the same API call
const mergeLogs = (logs: any[]) => {
  // Group logs by tool and timestamp window (use smaller window for better grouping)
  const groups: { [key: string]: any[] } = {}
  
  logs.forEach(log => {
    // Create a more precise grouping key using tool name and precise timestamp
    // Use timestamp down to seconds + tool name for better grouping
    const timestampSeconds = log.timestamp ? log.timestamp.substring(0, 19) : 'unknown' // YYYY-MM-DD HH:MM:SS
    const groupKey = `${log.tool_name || 'unknown'}_${timestampSeconds}`
    
    if (!groups[groupKey]) {
      groups[groupKey] = []
    }
    groups[groupKey].push(log)
  })
  
  const mergedLogs: any[] = []
  
  Object.keys(groups).forEach(groupKey => {
    const groupLogs = groups[groupKey]
    
    // If only one log in group, keep as is
    if (groupLogs.length === 1) {
      mergedLogs.push(groupLogs[0])
      return
    }
    
    // Sort group logs by category priority to find the best representative
    const categoryPriority = {
      'API_CALL_START': 1,
      'API_CALL_REQUEST_SUMMARY': 2,
      'API_CALL_COMPLETE': 3,
      'API_CALL_ERROR_RESPONSE': 4,
      'API_CALL_ERROR': 5,
      'API_CALL_RESPONSE': 6,
      'API_CALL_RESPONSE_BODY': 7
    }
    
    // Find the best representative log (prefer request summary or start)
    const startLog = groupLogs.find(log => log.category === 'API_CALL_START')
    const summaryLog = groupLogs.find(log => log.category === 'API_CALL_REQUEST_SUMMARY')
    const completeLog = groupLogs.find(log => log.category === 'API_CALL_COMPLETE')
    const errorLog = groupLogs.find(log => log.category === 'API_CALL_ERROR_RESPONSE' || log.category === 'API_CALL_ERROR')
    
    // Determine the main log to use as the merged record (prefer meaningful request info)
    const mainLog = summaryLog || startLog || completeLog || errorLog || groupLogs[0]
    
    // Extract key information from different log types
    const statusCode = groupLogs.find(log => log.status_code)?.status_code || mainLog.status_code
    const duration = completeLog?.duration || groupLogs.find(log => log.duration)?.duration
    const url = summaryLog?.url || startLog?.url || groupLogs.find(log => log.url)?.url
    const method = groupLogs.find(log => log.method)?.method || mainLog.method
    
    // Determine if there was an error
    const hasError = groupLogs.some(log => log.level === 'ERROR' || log.category.includes('ERROR'))
    const isSuccess = statusCode && statusCode >= 200 && statusCode < 400
    
    // Create merged log entry
    const mergedLog = {
      ...mainLog,
      category: 'API_CALL_MERGED', // New category for merged logs
      message: generateMergedMessage(groupLogs, mainLog, hasError, isSuccess, duration),
      merged_details: groupLogs.sort((a, b) => {
        // Sort details by timestamp for timeline display
        return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
      }),
      duration: duration,
      status_code: statusCode,
      url: url,
      method: method,
      level: hasError ? 'ERROR' : mainLog.level
    }
    
    mergedLogs.push(mergedLog)
  })
  
  return mergedLogs.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
}

// Generate a meaningful message for the merged log
const generateMergedMessage = (groupLogs: any[], mainLog: any, hasError?: boolean, isSuccess?: boolean, duration?: string) => {
  // Extract meaningful information from logs
  const summaryLog = groupLogs.find(log => log.category === 'API_CALL_REQUEST_SUMMARY')
  const startLog = groupLogs.find(log => log.category === 'API_CALL_START')
  const completeLog = groupLogs.find(log => log.category === 'API_CALL_COMPLETE')
  const errorLog = groupLogs.find(log => log.level === 'ERROR')
  
  // Try to extract request details from summary log
  let requestInfo = ''
  if (summaryLog && summaryLog.details) {
    try {
      const summary = JSON.parse(summaryLog.details)
      const method = summary.method || 'API'
      const endpoint = summary.url ? summary.url.split('/').pop() || 'endpoint' : 'endpoint'
      requestInfo = `${method.toUpperCase()} ${endpoint}`
    } catch {
      requestInfo = '接口调用'
    }
  } else if (startLog) {
    requestInfo = startLog.message || '接口调用'
  } else {
    requestInfo = '接口调用'
  }
  
  // Generate status message
  if (hasError) {
    const errorMessage = errorLog?.message || 'Unknown error'
    return `${requestInfo} - 失败: ${errorMessage}`
  } else if (isSuccess) {
    const durationText = duration ? ` (${duration})` : ''
    return `${requestInfo} - 成功${durationText}`
  } else if (completeLog) {
    const durationText = duration ? ` (${duration})` : ''
    return `${requestInfo} - 完成${durationText}`
  }
  
  return `${requestInfo} - 进行中`
}

// Extract URL from log details
const extractUrlFromDetails = (groupLogs: any[]) => {
  for (const log of groupLogs) {
    if (log.url) return log.url
    if (log.details && typeof log.details === 'string') {
      try {
        const details = JSON.parse(log.details)
        if (details.url) return details.url
      } catch {}
    }
  }
  return ''
}

// Log event handlers
const handleViewLogs = async (toolId: string) => {
  const tool = tools.value.find(t => t.id === toolId)
  if (!tool) return
  
  selectedToolName.value = tool.name
  selectedToolId.value = toolId
  logDialogVisible.value = true
  
  // Get MCP technical names for this tool
  try {
    const mcpNamesResponse = await axios.get(`${API_BASE_URL}/tools/${toolId}/mcp-names`)
    const mcpNames = mcpNamesResponse.data.mcp_tool_names || {}
    
    // Store MCP names for later use in refresh/filter functions
    currentMcpNames.value = Object.values(mcpNames) as string[]
    
    // Fetch logs for all MCP technical names associated with this tool
    const allLogs: any[] = []
    for (const [endpointKey, mcpTechName] of Object.entries(mcpNames)) {
      try {
        await fetchToolLogs(mcpTechName as string)
        allLogs.push(...selectedToolLogs.value)
      } catch (error) {
        console.warn(`Failed to fetch logs for ${mcpTechName}:`, error)
      }
    }
    
    // Remove duplicates and sort by timestamp
    const uniqueLogs = allLogs.filter((log, index, self) => 
      index === self.findIndex(l => 
        l.timestamp === log.timestamp && l.message === log.message
      )
    ).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
    
    // Apply log merging
    const mergedLogs = mergeLogs(uniqueLogs)
    selectedToolLogs.value = mergedLogs
    
    // 在这里显示汇总消息
    if (mergedLogs.length === 0) {
      ElMessage({
        message: `工具 "${tool.name}" 暂无调用日志，可能尚未被使用`,
        type: 'info',
        duration: 3000,
        showClose: true,
        grouping: true
      })
    } else {
      ElMessage({
        message: `成功获取 ${mergedLogs.length} 条日志记录`,
        type: 'success',
        duration: 3000,
        showClose: true,
        grouping: true
      })
    }
  } catch (error) {
    console.error('Failed to get MCP names for tool:', error)
    // Clear MCP names on error
    currentMcpNames.value = []
    // Fallback to original method
    await fetchToolLogs(tool.name)
  }
}

const handleRefreshLogs = async () => {
  // Use MCP technical names if available, otherwise fallback to display name
  if (currentMcpNames.value.length > 0) {
    const allLogs: any[] = []
    for (const mcpTechName of currentMcpNames.value) {
      try {
        await fetchToolLogs(mcpTechName)
        allLogs.push(...selectedToolLogs.value)
      } catch (error) {
        console.warn(`Failed to fetch logs for ${mcpTechName}:`, error)
      }
    }
    
    // Remove duplicates and sort by timestamp
    const uniqueLogs = allLogs.filter((log, index, self) => 
      index === self.findIndex(l => 
        l.timestamp === log.timestamp && l.message === log.message
      )
    ).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
    
    // Apply log merging
    selectedToolLogs.value = mergeLogs(uniqueLogs)
  } else {
    await fetchToolLogs(selectedToolName.value)
    selectedToolLogs.value = mergeLogs(selectedToolLogs.value)
  }
  ElMessage({
    message: '日志已刷新',
    type: 'success',
    duration: 2000,
    showClose: true,
    grouping: true
  })
}

const handleLogFilterChange = async () => {
  // Use MCP technical names if available, otherwise fallback to display name
  if (currentMcpNames.value.length > 0) {
    const allLogs: any[] = []
    for (const mcpTechName of currentMcpNames.value) {
      try {
        await fetchToolLogs(mcpTechName)
        allLogs.push(...selectedToolLogs.value)
      } catch (error) {
        console.warn(`Failed to fetch logs for ${mcpTechName}:`, error)
      }
    }
    
    // Remove duplicates and sort by timestamp
    const uniqueLogs = allLogs.filter((log, index, self) => 
      index === self.findIndex(l => 
        l.timestamp === log.timestamp && l.message === log.message
      )
    ).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
    
    // Apply log merging
    selectedToolLogs.value = mergeLogs(uniqueLogs)
  } else {
    await fetchToolLogs(selectedToolName.value)
    selectedToolLogs.value = mergeLogs(selectedToolLogs.value)
  }
}

const handleGetUrl = async (toolId: string) => {
  try {
    const response = await axios.get(`${API_BASE_URL}/tools/${toolId}/mcp-url`)
    ElMessageBox.alert(response.data.mcp_url, 'MCP URL', {
      confirmButtonText: '复制并关闭',
      callback: (action: string) => {
        if (action === 'confirm') {
          navigator.clipboard.writeText(response.data.mcp_url)
          ElMessage({
            message: '已复制到剪贴板！',
            type: 'success',
            duration: 2000,
            showClose: true,
            grouping: true
          })
        }
      },
    })
  } catch (error) {
    ElMessage({
      message: '获取 MCP URL 失败。',
      type: 'error',
      duration: 3000,
      showClose: true,
      grouping: true
    })
    console.error(error)
  }
}

const handleEdit = (toolId: string) => {
  router.push(`/tools/${toolId}/edit`)
}

const handleDelete = (toolId: string) => {
  ElMessageBox.confirm('确定要删除这个工具吗？此操作不可撤销。', '警告', {
    confirmButtonText: '确定删除',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      try {
        await axios.delete(`${API_BASE_URL}/tools/${toolId}`)
    ElMessage({
      message: '工具已删除。',
      type: 'success',
      duration: 3000,
      showClose: true,
      grouping: true
    })
        // Refresh the list after deletion
        fetchTools()
      } catch (error) {
        ElMessage.error('删除工具失败。')
        console.error(error)
      }
    })
    .catch(() => {
      // User cancelled
    })
}
</script>

<template>
  <div class="dashboard">
    <div class="dashboard-header">
      <h1>工具仪表盘</h1>
      <el-button type="primary" @click="router.push('/tools/new')">创建新工具</el-button>
    </div>

    <!-- Grid for tools -->
    <el-row v-if="tools.length > 0" :gutter="20" class="tool-grid">
      <el-col
        v-for="tool in tools"
        :key="tool.id"
        :xs="24" :sm="12" :md="8" :lg="6"
      >
        <ToolCard
          :tool="tool"
          @get-url="handleGetUrl"
          @edit="handleEdit"
          @delete="handleDelete"
          @view-logs="handleViewLogs"
        />
      </el-col>
    </el-row>

    <!-- Empty state -->
    <div v-else class="empty-state">
      <el-empty description="暂无工具">
        <el-button type="primary" @click="router.push('/tools/new')">立即创建第一个工具</el-button>
      </el-empty>
    </div>

    <!-- Log Dialog -->
    <el-dialog 
      v-model="logDialogVisible" 
      :title="`${selectedToolName} - 调用日志`" 
      width="90%"
      :before-close="() => { logDialogVisible = false; selectedToolLogs = []; currentMcpNames = []; selectedToolId = ''; expandedRows = []; }"
    >
      <div class="log-dialog-content">
        <!-- Filter Controls -->
        <div class="log-filters">
          <el-select v-model="logLevel" placeholder="选择日志级别" clearable @change="handleLogFilterChange">
            <el-option label="全部" value="" />
            <el-option label="ERROR" value="ERROR" />
            <el-option label="WARN" value="WARN" />
            <el-option label="INFO" value="INFO" />
            <el-option label="DEBUG" value="DEBUG" />
          </el-select>
          <el-select v-model="logLimit" @change="handleLogFilterChange">
            <el-option label="最近 50 条" :value="50" />
            <el-option label="最近 100 条" :value="100" />
            <el-option label="最近 200 条" :value="200" />
          </el-select>
          <el-button type="primary" @click="handleRefreshLogs">刷新日志</el-button>
        </div>

        <!-- Log Table - 只在有数据时显示 -->
        <el-table 
          v-if="selectedToolLogs.length > 0"
          :data="selectedToolLogs" 
          style="width: 100%" 
          height="500"
          :row-class-name="(row: any) => row.level === 'ERROR' ? 'error-row' : ''"
          :expand-row-keys="expandedRows"
          row-key="timestamp"
        >
          <!-- 展开行 -->
          <el-table-column type="expand">
            <template #default="props">
              <div v-if="isRowExpanded(props.row)" class="log-detail-content">
                <!-- For merged logs, show the complete request lifecycle -->
                <div v-if="props.row.category === 'API_CALL_MERGED' && props.row.merged_details">
                  <div class="log-detail-section">
                    <h4>请求概览</h4>
                    <div class="detail-item"><strong>时间:</strong> {{ formatTimestamp(props.row.timestamp) }}</div>
                    <div class="detail-item"><strong>工具:</strong> {{ props.row.tool_name }}</div>
                    <div v-if="props.row.method" class="detail-item"><strong>方法:</strong> {{ props.row.method }}</div>
                    <div v-if="props.row.status_code" class="detail-item"><strong>状态码:</strong> {{ props.row.status_code }}</div>
                    <div v-if="props.row.duration" class="detail-item"><strong>耗时:</strong> {{ props.row.duration }}</div>
                    <div v-if="props.row.url" class="detail-item"><strong>URL:</strong> {{ props.row.url }}</div>
                  </div>
                  
                  <!-- Show detailed request lifecycle -->
                  <div class="log-detail-section">
                    <h4>请求生命周期 ({{ props.row.merged_details.length }} 步骤)</h4>
                    <div class="request-timeline">
                      <div 
                        v-for="(detail, index) in props.row.merged_details" 
                        :key="index" 
                        class="timeline-item"
                        :class="{ 'error': detail.level === 'ERROR' }"
                      >
                        <div class="timeline-marker"></div>
                        <div class="timeline-content">
                          <div class="timeline-header">
                            <span class="timeline-category">{{ formatCategoryDisplay(detail.category) }}</span>
                            <span class="timeline-level" :class="detail.level.toLowerCase()">{{ detail.level }}</span>
                            <span class="timeline-time">{{ formatTimestamp(detail.timestamp) }}</span>
                          </div>
                          <div class="timeline-message">{{ detail.message }}</div>
                          <div v-if="detail.details" class="timeline-details">
                            <pre>{{ formatDetailsContent(detail.details) }}</pre>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                
                <!-- For non-merged logs, show standard detail view -->
                <div v-else>
                  <div class="log-detail-section">
                    <h4>基本信息</h4>
                    <div class="detail-item"><strong>时间:</strong> {{ formatTimestamp(props.row.timestamp) }}</div>
                    <div class="detail-item"><strong>工具:</strong> {{ props.row.tool_name }}</div>
                    <div class="detail-item"><strong>类别:</strong> {{ props.row.category }}</div>
                    <div class="detail-item"><strong>级别:</strong> {{ props.row.level }}</div>
                    <div v-if="props.row.method" class="detail-item"><strong>方法:</strong> {{ props.row.method }}</div>
                    <div v-if="props.row.status_code" class="detail-item"><strong>状态码:</strong> {{ props.row.status_code }}</div>
                    <div v-if="props.row.duration" class="detail-item"><strong>耗时:</strong> {{ props.row.duration }}</div>
                  </div>
                  
                  <div v-if="props.row.url" class="log-detail-section">
                    <h4>请求URL</h4>
                    <div class="url-content">{{ props.row.url }}</div>
                  </div>
                  
                  <div v-if="props.row.message" class="log-detail-section">
                    <h4>消息</h4>
                    <div class="message-content">{{ props.row.message }}</div>
                  </div>
                  
                  <div v-if="props.row.details" class="log-detail-section">
                    <h4>详细信息</h4>
                    <pre class="details-content">{{ formatDetailsContent(props.row.details) }}</pre>
                  </div>
                </div>
              </div>
            </template>
          </el-table-column>
          
          <el-table-column prop="timestamp" label="时间" width="160">
            <template #default="scope">
              <span :title="scope.row.timestamp || 'N/A'">
                {{ formatTimestamp(scope.row.timestamp) }}
              </span>
            </template>
          </el-table-column>
          
          <el-table-column prop="level" label="级别" width="70">
            <template #default="scope">
              <el-tag :type="getLogLevelTagType(scope.row.level)" size="small">
                {{ scope.row.level }}
              </el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="category" label="类别" width="180">
            <template #default="scope">
              <el-tag 
                :type="getCategoryTagType(scope.row.category)" 
                size="small"
                :title="scope.row.category"
              >
                {{ formatCategoryDisplay(scope.row.category) }}
              </el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="message" label="消息" min-width="250" show-overflow-tooltip />
          
          <el-table-column prop="status_code" label="状态码" width="80">
            <template #default="scope">
              <el-tag 
                v-if="scope.row.status_code" 
                :type="getStatusCodeTagType(scope.row.status_code)" 
                size="small"
              >
                {{ scope.row.status_code }}
              </el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="duration" label="耗时" width="100" show-overflow-tooltip />
          
          <el-table-column prop="method" label="方法" width="80" show-overflow-tooltip />
          
          <el-table-column label="操作" width="80">
            <template #default="scope">
              <el-button 
                size="small" 
                type="primary" 
                link
                @click="toggleRowExpansion(scope.row)"
              >
                {{ isRowExpanded(scope.row) ? '收起' : '详情' }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- Empty state for logs -->
        <div v-if="selectedToolLogs.length === 0" class="log-empty-state">
          <el-empty description="暂无日志数据">
            <p>该工具还没有任何调用记录，或者日志已被清理。</p>
            <p>当 AI 调用此工具时，相关的 API 请求日志会在这里显示。</p>
          </el-empty>
        </div>
      </div>
    </el-dialog>

  </div>
</template>

<style scoped>
.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
}

h1 {
  color: #E6EDF3;
  font-size: 2rem;
}

.tool-grid {
  width: 100%;
}

.el-col {
  margin-bottom: 20px;
}

.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  height: calc(100vh - 250px); /* Adjust height to be vertically centered */
}

/* Log Dialog Styles */
.log-dialog-content {
  max-height: 600px;
}

.log-filters {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
  align-items: center;
  background-color: #ffffff;
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  border: 1px solid #e1e5eb;
}

.log-empty-state {
  padding: 60px;
  text-align: center;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  border: 1px solid #e1e5eb;
}

.log-empty-state p {
  color: #718096;
  margin: 12px 0;
  font-size: 15px;
}

/* Log detail content styles */
.log-detail-content {
  padding: 16px;
  background: #1a1a1a;
  border-radius: 8px;
  margin: 12px 0;
  border: 1px solid #333;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.log-detail-section {
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #333;
}

.log-detail-section:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.log-detail-section h4 {
  color: #58a6ff;
  margin: 0 0 12px 0;
  font-size: 15px;
  font-weight: 600;
  padding-bottom: 8px;
  border-bottom: 2px solid #333;
}

.detail-item {
  margin: 6px 0;
  font-size: 14px;
  color: #e6edf3;
  line-height: 1.6;
  display: flex;
}

.detail-item strong {
  color: #58a6ff;
  margin-right: 12px;
  font-weight: 600;
  min-width: 70px;
  display: inline-block;
}

.url-content,
.message-content {
  background: #242424;
  padding: 12px 16px;
  border-radius: 6px;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace;
  font-size: 13px;
  color: #e6edf3;
  word-break: break-all;
  border: 1px solid #333;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  line-height: 1.5;
}

.details-content {
  background: #242424;
  padding: 16px;
  border-radius: 6px;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace;
  font-size: 12px;
  color: #e6edf3;
  white-space: pre-wrap;
  overflow-x: auto;
  max-height: 350px;
  margin: 0;
  border: 1px solid #333;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  line-height: 1.6;
}

/* Timeline styles for merged logs */
.request-timeline {
  position: relative;
  padding-left: 24px;
}

.timeline-item {
  position: relative;
  margin-bottom: 20px;
  padding-left: 20px;
}

.timeline-item::before {
  content: '';
  position: absolute;
  left: -11px;
  top: 10px;
  bottom: -20px;
  width: 2px;
  background: #333;
}

.timeline-item:last-child::before {
  bottom: auto;
  height: 20px;
}

.timeline-marker {
  position: absolute;
  left: -15px;
  top: 8px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #58a6ff;
  border: 3px solid #1a1a1a;
  box-shadow: 0 0 0 2px #1a1a1a;
}

.timeline-item.error .timeline-marker {
  background: #f56c6c;
  box-shadow: 0 0 0 2px #1a1a1a;
}

.timeline-content {
  background: #242424;
  border-radius: 8px;
  padding: 16px;
  border: 1px solid #333;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.timeline-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.timeline-category {
  background: #0d6efd;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.timeline-level {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.timeline-level.error {
  background: #e53e3e;
  color: white;
}

.timeline-level.info {
  background: #0d6efd;
  color: white;
}

.timeline-level.debug {
  background: #6c757d;
  color: white;
}

.timeline-time {
  color: #8b949e;
  font-size: 12px;
  margin-left: auto;
}

.timeline-message {
  color: #e6edf3;
  font-size: 14px;
  margin-bottom: 10px;
  line-height: 1.5;
}

.timeline-details {
  background: #1a1a1a;
  border-radius: 6px;
  padding: 12px;
  max-height: 250px;
  overflow-y: auto;
  border: 1px solid #333;
}

.timeline-details pre {
  font-size: 11px;
  color: #8b949e;
  margin: 0;
  white-space: pre-wrap;
  line-height: 1.6;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace;
}

/* 表格样式优化 */
:deep(.el-table .el-table__cell) {
  padding: 10px 0;
  color: #e6edf3 !important;
  font-size: 14px;
  background-color: #0d1117 !important;
}

:deep(.el-table__header th) {
  background-color: #161b22 !important;
  color: #c9d1d9 !important;
  font-weight: 600;
  padding: 12px 0 !important;
}

:deep(.el-table__row) {
  background-color: #0d1117 !important;
}

:deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
  background-color: rgba(56, 139, 253, 0.15) !important;
}

/* 错误行高亮 */
:deep(.error-row) {
  background-color: rgba(229, 62, 62, 0.15) !important;
}

:deep(.error-row:hover > td) {
  background-color: rgba(229, 62, 62, 0.25) !important;
}

/* 表格边框和整体样式 */
:deep(.el-table) {
  border: 1px solid #30363d;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

:deep(.el-table__header-wrapper) {
  border-bottom: 1px solid #30363d;
}

/* 对话框样式 */
:deep(.el-dialog__body) {
  padding: 24px;
  background-color: #0d1117;
}

.log-filters {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
  align-items: center;
  background-color: #161b22;
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  border: 1px solid #30363d;
}

.log-empty-state {
  padding: 60px;
  text-align: center;
  background-color: #161b22;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  border: 1px solid #30363d;
}

.log-empty-state p {
  color: #8b949e;
  margin: 12px 0;
  font-size: 15px;
}
</style>
